package ne.aishuyuan.video.netty.client;

import cn.hutool.json.JSONUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import ne.aishuyuan.video.bean.Device;
import ne.aishuyuan.video.bean.Packet;
import ne.aishuyuan.video.bean.PlayMedia;
import ne.aishuyuan.video.netty.bean.Notice;
import ne.aishuyuan.video.utils.MessageUtil;
import ne.aishuyuan.video.view.Player;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@ChannelHandler.Sharable
public class NettyClientHandler extends SimpleChannelInboundHandler<Packet.Message> {
    @Autowired
    private Player player;
    private int readIdleCount = 0;

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                log.info("READER_IDLE: read timeout from "+ctx.channel().remoteAddress());
                readIdleCount ++;
            } else  if (event.state() == IdleState.WRITER_IDLE) {
                    //维持心跳数据发送
                    if (ctx.channel().isActive()) {
                        Device device = new Device("PF1SLEMF");
                        Packet.Message message = MessageUtil.buildMessage(device);
                        new Thread(() -> {
                            ctx.channel().writeAndFlush(message);
                        }).start();
                        log.info(">>>>>>>>>>>>>客户端上报心跳数据完毕 .....");
                    }
            }

            if (readIdleCount > 3) {
                log.info(">>>>>>>>>>>>>>>>>三次读空闲关闭连接");
                ctx.disconnect();
            }
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info(">>>>>>>>>>>>>客户端Active .....");
        //上报deviceInfo，先写死，后续是根据真实设备号来.
        Device device = new Device("PF1SLEMF");
        Packet.Message message = MessageUtil.buildMessage(device);
        ctx.channel().writeAndFlush(message);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Packet.Message msg) throws Exception {
        Packet.Message packet =  msg;
        String message = new String(packet.getData().toByteArray(),"UTF-8");
        log.info(">>>>>>>>>>>>客户端收到协议消息,{}",message);
        Notice notice = JSONUtil.toBean(message,Notice.class);
        if (null != notice) {
            switch (notice.getType()) {
                case FOR_UP_DATE:
                    player.load();
                    break;
                case PAUSE:
                    player.pause();
                    break;
                case STOP:
                    player.stop();
                    break;
                case PLAY:
                    player.start();
                    break;
                case INSERT_PLAY:
                    PlayMedia insertMedia = notice.getData();
                    insertMedia.getResourceVos().forEach(item -> {
                        item.setPlayType(insertMedia.getType());
                    });
                    player.loadInsert(insertMedia);
                default:
            }
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}